#include <array>
#include <vector>

//#include <QMessageBox>
#include<debugx>
#include <iostream>


#ifndef DSTATE_STOPPING
#define DSTATE_STOPPING	210
#endif

//#include<jpegint.h>
#include<jpeglib.h>

#include "SignalData.h"
#include "qbuffer.h"

#include "png.h"
#include "zlib.h"

using namespace std;

#include "../ImageLib/TinyImageWrapper.h"

void imageDemo() {

    //  tiffMain();

    auto file = "d:/image/2k1.jpg";
    auto hander = Tiny_Load(file);
    Tiny_FlipV(hander);

    debugx("JPEG_LIB_VERSION:" << JPEG_LIB_VERSION);
    // jpgDemoMain();

    auto fp = fopen(file, "rb");
    if (!fp) {
        debugx("open fail: " << file);
        return;
    }

    try {
        //  readJpg(fp);
        debugx("readJpg end.");
    } catch (...) {
        debugx("readJpg exception.");
    }

    fclose(fp);

    return;
}



int readJpg1(FILE* hFile,uchar **buffer)
{
    debugx("");
    if(!hFile) return 0;
    fseek(hFile,0,SEEK_SET);

    //解码结构体
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);  //设置错误返回句柄
    jpeg_create_decompress(&cinfo);    //创建解码结构体
    jpeg_stdio_src(&cinfo, hFile);     //指定源文件
    jpeg_read_header(&cinfo, TRUE);  //获取文件信息

    auto image_size = cinfo.image_width*cinfo.image_height*cinfo.num_components ;
    qDebug()<<"\t width:"<<cinfo.image_width <<"  height:"<<cinfo.image_height <<"  num_components:"<<cinfo.num_components<<"  image_size:"<<image_size;

    //设置输出的颜色类型
    //设置图像bpp,若不是灰度图，统一转换到RGB空间
    int bpp;
    if(cinfo.out_color_space == JCS_GRAYSCALE) {bpp = 8;}
    else {cinfo.out_color_space = JCS_RGB; bpp = 24;}

    //按照bpp启动解码，输出图像
    jpeg_start_decompress(&cinfo);

    //获取图像高宽
    auto width = cinfo.output_width;
    auto height = cinfo.output_height;
    auto output_components = cinfo.output_components;



    /*
out_color_space：输出的颜色格式
typedef enum {
    JCS_UNKNOWN,       // error/unspecified
    JCS_GRAYSCALE,        // monochrome
        JCS_RGB,       // red/green/blue
        JCS_YCbCr,     //   Y/Cb/Cr (also known as YUV)
        JCS_CMYK,       // C/M/Y/K
        JCS_YCCK,       //  Y/Cb/Cr/K
} J_COLOR_SPACE;

不设置的话通常就是JCS_RGB，RGB888的格式
libjpeg支持对输出数据进行缩放（scale）,还可以设置缩放大小等，scale_num，scale_denom

*/
    //获取图像分辨率
    float xdpi,ydpi;
    if(cinfo.density_unit ==1) {xdpi=cinfo.X_density; ydpi=cinfo.Y_density;}  //英寸
    else if(cinfo.density_unit ==2) {xdpi=cinfo.X_density*2.54+0.5; ydpi = cinfo.Y_density*2.54+0.5;} //厘米
    else {xdpi = ydpi = 0;} //未知


    qDebug()<<"\t width:"<<width <<"  height:"<<height <<"  num_components:"<<output_components;
    qDebug()<<"\t xdpi:"<<xdpi<<"  ydpi:"<<ydpi;



    //    auto format=QImage::Format_RGB32;
    //    //  format=QImage::Format_Grayscale8;
    //    QImage img(width,height,format);
    //    auto bits=img.bits();
    //解码到内存
    JSAMPROW row_pointer[1];

    while (cinfo.output_scanline < cinfo.output_height)
    {
        uchar* pPrt = buffer[(cinfo.output_scanline)*cinfo.image_width*cinfo.num_components];
        row_pointer[0] = pPrt;
        jpeg_read_scanlines(&cinfo, row_pointer, 1);
    }


    qDebug()<<"\t msg_code: "<<jerr.msg_code<<"\n\t global_state: "<<cinfo.global_state;
    cinfo.global_state=DSTATE_STOPPING;
    //清理内存
    jpeg_finish_decompress(&cinfo);
    debugx("before jpeg_destroy_decompress");
    jpeg_destroy_decompress(&cinfo);

    //    auto pix = QPixmap::fromImage(img);
    //    lblImage->setPixmap(pix.scaled(lblImage->size(), Qt::KeepAspectRatio,
    //                                   Qt::SmoothTransformation));

    return 0;
}
int pngTestMain1() {
    debugx("\n Testing libpng version:" << PNG_LIBPNG_VER_STRING);
    qDebug() << "   with zlib   version " << ZLIB_VERSION;
    qDebug() << png_get_copyright(NULL);
    qDebug() << " library  : " << (unsigned long)png_access_version_number()
             << png_get_header_version(NULL);

    /* Show the version of libpng used in building the application */
    qDebug() << " pngtest  :" << (unsigned long)PNG_LIBPNG_VER
             << PNG_HEADER_VERSION_STRING;

    if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) {
        qDebug() << "Warning: versions are different between png.h and png.c\n";
        qDebug() << "  png.h version: " << PNG_LIBPNG_VER_STRING;
        qDebug() << "  png.c version: " << png_libpng_ver;
    }
}

void buffDemo()
{
    QByteArray bytearray;
    QBuffer buffer(&bytearray);

    if(!buffer.open(QIODevice::ReadWrite))
    {
        //   QMessageBox::warning(NULL, QString::fromLocal8Bit("提示："), QString::fromLocal8Bit("Buffer文件打开失败"));
    }

    QDataStream data(&buffer);
    data.setVersion(QDataStream::Qt_5_9);

    data.writeBytes("12345", 5);
    data.writeBytes("67890", 7);

    buffer.seek(0);
    unsigned int len;
    char* array = new char[10];

    data.readBytes(array, len);
    qDebug() << array;
    data.readBytes(array, len);
    qDebug() << array;
    //  buffer.close();

    qDebug() <<buffer.size();


    QString hello;
    data<<"hello 1234";
    data>>hello;

    qDebug() <<buffer.size();
    debugx(hello);

    qDebug() <<"\n\n\t ----";
}

int readJpg(FILE* hFile)
{
    if(!hFile) return 0;
    fseek(hFile,0,SEEK_SET);

    //解码结构体
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);  //设置错误返回句柄
    jpeg_create_decompress(&cinfo);    //创建解码结构体
    jpeg_stdio_src(&cinfo, hFile);     //指定源文件
    (void) jpeg_read_header(&cinfo, TRUE);  //获取文件信息

    //设置图像bpp,若不是灰度图，统一转换到RGB空间
    int bpp;
    if(cinfo.out_color_space == JCS_GRAYSCALE) {bpp = 8;}
    else {cinfo.out_color_space = JCS_RGB; bpp = 24;}

    //按照bpp启动解码，输出图像
    (void) jpeg_start_decompress(&cinfo);

    //获取图像高宽
    tiny_int width = cinfo.output_width;
    tiny_int height = cinfo.output_height;

    //获取图像分辨率
    float xdpi,ydpi;
    if(cinfo.density_unit ==1) {xdpi=cinfo.X_density; ydpi=cinfo.Y_density;}  //英寸
    else if(cinfo.density_unit ==2) {xdpi=cinfo.X_density*2.54+0.5; ydpi = cinfo.Y_density*2.54+0.5;} //厘米
    else {xdpi = ydpi = 0;} //未知


    debugx("\n\t width:"<<width<<"  height:"<<height);
    debugx("\n\t xdpi:"<<xdpi<<"  ydpi:"<<ydpi);
    //清理内存
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    return 0;
}
